using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Matrix.Notification.Domain.Shared.Notifications;

namespace Matrix.Notification.Domain.Notifications
{
    /// <summary>
    /// 通知批次仓储接口
    /// </summary>
    public interface INotificationBatchRepository : IRepository<NotificationBatch, Guid>
    {
        /// <summary>
        /// 根据名称获取批次
        /// </summary>
        Task<NotificationBatch?> GetByNameAsync(
            string name,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据编码获取批次
        /// </summary>
        Task<NotificationBatch?> GetByCodeAsync(
            string batchCode,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据外部批次ID获取批次
        /// </summary>
        Task<NotificationBatch?> GetByExternalBatchIdAsync(
            string externalBatchId,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据状态获取批次列表
        /// </summary>
        Task<List<NotificationBatch>> GetByStatusAsync(
            NotificationBatchStatus status,
            Guid? tenantId = null,
            NotificationBatchType? type = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据类型获取批次列表
        /// </summary>
        Task<List<NotificationBatch>> GetByTypeAsync(
            NotificationBatchType type,
            Guid? tenantId = null,
            NotificationBatchStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据发送者ID获取批次列表
        /// </summary>
        Task<List<NotificationBatch>> GetBySenderIdAsync(
            Guid senderId,
            Guid? tenantId = null,
            NotificationBatchStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据模板ID获取批次列表
        /// </summary>
        Task<List<NotificationBatch>> GetByTemplateIdAsync(
            Guid templateId,
            Guid? tenantId = null,
            NotificationBatchStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据通知类型获取批次列表
        /// </summary>
        Task<List<NotificationBatch>> GetByNotificationTypeAsync(
            NotificationType notificationType,
            Guid? tenantId = null,
            NotificationBatchStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取待发送的批次
        /// </summary>
        Task<List<NotificationBatch>> GetPendingBatchesAsync(
            DateTime? beforeTime = null,
            Guid? tenantId = null,
            int maxResultCount = 10,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取正在发送的批次
        /// </summary>
        Task<List<NotificationBatch>> GetSendingBatchesAsync(
            Guid? tenantId = null,
            int maxResultCount = 10,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取已调度的批次
        /// </summary>
        Task<List<NotificationBatch>> GetScheduledBatchesAsync(
            DateTime? beforeTime = null,
            Guid? tenantId = null,
            int maxResultCount = 10,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取暂停的批次
        /// </summary>
        Task<List<NotificationBatch>> GetPausedBatchesAsync(
            Guid? tenantId = null,
            int maxResultCount = 10,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据关联实体获取批次
        /// </summary>
        Task<List<NotificationBatch>> GetByRelatedEntityAsync(
            Guid? entityId = null,
            string? entityType = null,
            Guid? tenantId = null,
            NotificationBatchStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据分类获取批次
        /// </summary>
        Task<List<NotificationBatch>> GetByCategoryAsync(
            string category,
            Guid? tenantId = null,
            NotificationBatchStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据标签搜索批次
        /// </summary>
        Task<List<NotificationBatch>> SearchByTagsAsync(
            string[] tags,
            Guid? tenantId = null,
            NotificationBatchStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据关键词搜索批次
        /// </summary>
        Task<List<NotificationBatch>> SearchAsync(
            string keyword,
            Guid? tenantId = null,
            NotificationBatchType? type = null,
            NotificationBatchStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取热门批次
        /// </summary>
        Task<List<NotificationBatch>> GetPopularBatchesAsync(
            int maxResultCount = 10,
            Guid? tenantId = null,
            DateTime? since = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取最近创建的批次
        /// </summary>
        Task<List<NotificationBatch>> GetRecentlyCreatedBatchesAsync(
            int maxResultCount = 10,
            Guid? tenantId = null,
            DateTime? since = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取成功率高的批次
        /// </summary>
        Task<List<NotificationBatch>> GetHighSuccessRateBatchesAsync(
            double minSuccessRate = 90.0,
            int maxResultCount = 10,
            Guid? tenantId = null,
            DateTime? since = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取大批次（接收者数量多的）
        /// </summary>
        Task<List<NotificationBatch>> GetLargeBatchesAsync(
            int minRecipients = 1000,
            int maxResultCount = 10,
            Guid? tenantId = null,
            NotificationBatchStatus? status = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查批次名称是否存在
        /// </summary>
        Task<bool> NameExistsAsync(
            string name,
            Guid? excludeId = null,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查批次编码是否存在
        /// </summary>
        Task<bool> CodeExistsAsync(
            string batchCode,
            Guid? excludeId = null,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取批次统计信息
        /// </summary>
        Task<BatchStatistics> GetStatisticsAsync(
            Guid? tenantId = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量更新批次状态
        /// </summary>
        Task<int> UpdateStatusAsync(
            List<Guid> batchIds,
            NotificationBatchStatus newStatus,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量暂停批次
        /// </summary>
        Task<int> PauseBatchesAsync(
            List<Guid> batchIds,
            string? reason = null,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量恢复批次
        /// </summary>
        Task<int> ResumeBatchesAsync(
            List<Guid> batchIds,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量取消批次
        /// </summary>
        Task<int> CancelBatchesAsync(
            List<Guid> batchIds,
            string? reason = null,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 自动清理已完成的批次
        /// </summary>
        Task<int> CleanupCompletedBatchesAsync(
            DateTime? beforeTime = null,
            int maxResultCount = 1000,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取需要自动处理的批次
        /// </summary>
        Task<List<NotificationBatch>> GetBatchesForAutoProcessingAsync(
            DateTime? beforeTime = null,
            Guid? tenantId = null,
            int maxResultCount = 10,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 更新批次进度
        /// </summary>
        Task<int> UpdateBatchProgressAsync(
            Guid batchId,
            int sentCount,
            int deliveredCount,
            int failedCount,
            int readCount,
            int confirmedCount,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取超时的批次
        /// </summary>
        Task<List<NotificationBatch>> GetTimeoutBatchesAsync(
            DateTime? beforeTime = null,
            Guid? tenantId = null,
            int maxResultCount = 10,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 重置批次统计
        /// </summary>
        Task<int> ResetBatchStatisticsAsync(
            List<Guid> batchIds,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);
    }

    /// <summary>
    /// 批次统计信息
    /// </summary>
    public class BatchStatistics
    {
        /// <summary>
        /// 总批次数
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// 按状态统计
        /// </summary>
        public Dictionary<NotificationBatchStatus, int> CountByStatus { get; set; } = new();

        /// <summary>
        /// 按类型统计
        /// </summary>
        public Dictionary<NotificationBatchType, int> CountByType { get; set; } = new();

        /// <summary>
        /// 按通知类型统计
        /// </summary>
        public Dictionary<NotificationType, int> CountByNotificationType { get; set; } = new();

        /// <summary>
        /// 总接收者数量
        /// </summary>
        public int TotalRecipients { get; set; }

        /// <summary>
        /// 总已发送数量
        /// </summary>
        public int TotalSentCount { get; set; }

        /// <summary>
        /// 总已送达数量
        /// </summary>
        public int TotalDeliveredCount { get; set; }

        /// <summary>
        /// 总失败数量
        /// </summary>
        public int TotalFailedCount { get; set; }

        /// <summary>
        /// 总已读数量
        /// </summary>
        public int TotalReadCount { get; set; }

        /// <summary>
        /// 总已确认数量
        /// </summary>
        public int TotalConfirmedCount { get; set; }

        /// <summary>
        /// 平均成功率
        /// </summary>
        public double AverageSuccessRate { get; set; }

        /// <summary>
        /// 平均读取率
        /// </summary>
        public double AverageReadRate { get; set; }

        /// <summary>
        /// 平均确认率
        /// </summary>
        public double AverageConfirmationRate { get; set; }

        /// <summary>
        /// 平均发送时间（毫秒）
        /// </summary>
        public double AverageSendTimeMs { get; set; }

        /// <summary>
        /// 平均批次大小
        /// </summary>
        public double AverageBatchSize { get; set; }

        /// <summary>
        /// 最大批次大小
        /// </summary>
        public int MaxBatchSize { get; set; }

        /// <summary>
        /// 最小批次大小
        /// </summary>
        public int MinBatchSize { get; set; }

        /// <summary>
        /// 总发送时间（毫秒）
        /// </summary>
        public double TotalSendTimeMs { get; set; }

        /// <summary>
        /// 平均发送速率（每秒）
        /// </summary>
        public double AverageSendRatePerSecond { get; set; }

        /// <summary>
        /// 完成的批次数
        /// </summary>
        public int CompletedCount { get; set; }

        /// <summary>
        /// 取消的批次数
        /// </summary>
        public int CancelledCount { get; set; }

        /// <summary>
        /// 失败的批次数
        /// </summary>
        public int FailedCount { get; set; }

        /// <summary>
        /// 暂停的批次数
        /// </summary>
        public int PausedCount { get; set; }
    }
}